package com.dj.mingkong.admin.boot.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.dj.mingkong.common.microservice.UserContext;
import com.dj.mingkong.common.util.ReflectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Objects;

@Component
public class DevopsRecordMetaObjectHandler implements MetaObjectHandler {
    private static final Logger log = LoggerFactory.getLogger(DevopsRecordMetaObjectHandler.class);
    private static final String USER_ID = "user_id";
    private static final String USERNAME = "username";
    private static final String CREATE_PERSON = "createPerson";
    private static final String CREATE_TIME = "createTime";
    private static final String UPDATE_PERSON = "updatePerson";
    private static final String UPDATE_TIME = "updateTime";
    @Value("${dj.mybatis.plus.config.devops-field}")
    private String devopsField;
    @Value("${dj.mybatis.plus.config.timestampset:false}")
    private boolean timestampSet;

    @Override
    public void insertFill(MetaObject metaObject) {
        log.trace("start insert fill update_person.");
        if (metaObject.hasSetter(CREATE_PERSON) && Objects.isNull(metaObject.getValue(CREATE_PERSON))) {
            Object fieldValue;
            if (USER_ID.equals(this.devopsField)) {
                metaObject.setValue(CREATE_PERSON, this.wrapIdFiled(UserContext.getUserId()));
            } else if (USERNAME.equals(this.devopsField)) {
                metaObject.setValue(CREATE_PERSON, this.wrapFiled(UserContext.getUsername()));
            } else if ((fieldValue = ReflectUtils.getFieldValue(metaObject, this.devopsField)) != null) {
                metaObject.setValue(CREATE_PERSON, this.wrapFiled(String.valueOf(fieldValue)));
            }
        }

        if (this.timestampSet && metaObject.hasGetter(CREATE_TIME) && Objects.isNull(metaObject.getValue(CREATE_TIME))) {
            metaObject.setValue(CREATE_TIME, LocalDateTime.now());
        }

        this.updateFill(metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.trace("start update fill update_person.");
        if (metaObject.hasSetter(UPDATE_PERSON) && Objects.isNull(metaObject.getValue(UPDATE_PERSON))) {
            Object fieldValue;
            if (USER_ID.equals(this.devopsField)) {
                metaObject.setValue(UPDATE_PERSON, this.wrapIdFiled(UserContext.getUserId()));
            } else if (USERNAME.equals(this.devopsField)) {
                metaObject.setValue(UPDATE_PERSON, this.wrapFiled(UserContext.getUsername()));
            } else if ((fieldValue = ReflectUtils.getFieldValue(metaObject, this.devopsField)) != null) {
                metaObject.setValue(UPDATE_PERSON, this.wrapFiled(String.valueOf(fieldValue)));
            }
        }

        /*if (this.timestampSet && metaObject.hasGetter(UPDATE_TIME) && Objects.isNull(metaObject.getValue(UPDATE_TIME))) {
            metaObject.setValue(UPDATE_TIME, LocalDateTime.now().withNano(0));
        }*/

        if (this.timestampSet && metaObject.hasGetter(UPDATE_TIME)) {
            metaObject.setValue(UPDATE_TIME, LocalDateTime.now());
        }
    }

    private Long wrapIdFiled(Long id) {
        return id == null ? 0L : UserContext.getUserId();
    }

    private String wrapFiled(String str) {
        return StringUtils.isNotBlank(str) ? UserContext.getUsername() : "";
    }
}
